home *** CD-ROM | disk | FTP | other *** search
- ******************
- * *
- * TIMESET.ASM * Set TIME from clock cartridge
- * * <=> PUBLIC DOMAIN 09-SEP-86 <=>
- ******************
- *
- *** created: 07-JUN-86 by Tim Hunkler / Solar Powered Software
- *
- * --- symbol definitions
- *
- ROM3 equ $fa0000 ; address to strobe rom3 pin
- ROM4 equ $fb0000 ; address used to strobe rom4 pin
- READ equ 0 ; offset for RTC chip reads
- WRT equ 64 ; offset for RTC chip writes
- CR equ $0d ; carriage return
- LF equ $0a ; line feed
- BELL equ $07 ; sound the bell
-
- * ===============================
- * ----- PROGRAM ENTRY POINT -----
- * ===============================
- *
- x: lea x-16(pc),sp ; set up a very small stack (240 bytes)
- *
- * --- initialize the clock cartridge after power up
- *
- moveq #%0001,d0 ; load control bits
- moveq #0,d1 ; addr 0 = control register
- bsr w_clock ; enable clock, disable interrupts
- *
- * --- read the time from the cartridge
- *
- movea.l sp,a5 ; point a5 to temp buffer
- bsr r_clock ; retrieve the time
- move.w d0,-(sp) ; save error flag
- *
- * --- set the system time
- *
- bsr.s set_tos ; set the time if no error
- *
- * --- format and display the time
- *
- bsr tod_fmt ; format time for display
- lea title(pc),a0 ; point to title string
-
- tst.w (sp)+ ; error reading cartridge ?
- bge.s okfine ; no, skip
- lea errmsg(pc),a0 ; yes, change message
-
- okfine: bsr.s string ; display the string
- *
- * --- delay a bit before exiting
- *
- move.l #400000,d0 ; load delay count
- delay: subq.l #1,d0 ; loop till count reaches zero
- bne.s delay
- *
- * --- time to exit
- *
- clr.w -(sp) ; pass function code = 0
- trap #1 ; call the system (never return)
- page
- * ======================================
- * ===== string : display a string =====
- * ======================================
- *
- * in: A0.L = string address
- * out: none
- * changed: many
- *
- * This subroutine displays the null terminated string whose address is
- * passed in A0 at the current cursor location on the screen.
- *
- string: move.l a0,-(sp) ; pass string address on stack
- move.w #9,-(sp) ; function 9 = text output
- trap #1 ; system call
- addq.l #6,sp ; fix stack
- rts
-
- * ========================================================
- * ===== fetch2 : convert next two digits to a number =====
- * ========================================================
- *
- * in: A0.L = address of digits
- * out: D0.L = value of conversion
- * A0.L = updated by 2
- * cc's : set by D0
- * changed: D1
- *
- * This subroutine converts the two ASCII digits pointed to by the
- * address in A0 into a binary value.
- *
- fetch2: moveq #%1111,d0 ; load mask
- and.b (a0)+,d0 ; get 10's digit
- moveq #%1111,d1 ; load mask
- and.b (a0)+,d1 ; get 1's digit
- mulu #10,d0 ; x 10
- add.w d1,d0 ; result = d0 x 10 + d1
- rts
-
- * ====================================================
- * ===== set_tos : Set the time and date for TOS =====
- * ====================================================
- *
- * in: A5.L = address of buffer returned by r_clock
- * D0.W = negative value if default time desired
- * out: D7.L = date/time encoded like TOS likes it
- *
- * changed: A0,A1,A2,D1,D2
- *
- * This subroutine uses the data retrieved from the clock cartridge and
- * stored in a formatted buffer and converts this information into a
- * format suitable for setting the time of both TOS and GEM. System
- * calls are then performed for changing the time and date.
- *
- set_tos:
- move.l #$0C215000,d7 ; preload 01/01/86 10:00:00
- tst.w d0 ; do we want default or real time?
- bmi.s stdef ; branch for default
- *
- * --- format the date: [yyyyyyy mmmm ddddd]
- *
- lea 2(a5),a0 ; point to first year digit
- bsr.s fetch2 ; get year (00= 1980)
- move.l d0,d7 ; place year into d7
-
- bsr.s fetch2 ; get month, 1..12
- lsl.w #4,d7 ; form: ????? yyyyyyy 0000
- or.w d0,d7 ; add in the month
-
- bsr.s fetch2 ; get day of month, 1..31
- lsl.w #5,d7 ; form: yyyyyyy mmmm 00000
- or.w d0,d7 ; add in the day
- *
- * --- encode the time: [hhhhh mmmmmm sssss]
- *
- swap d7 ; put year/month/day in upper word
-
- bsr.s fetch2 ; get hour, 0..23
- move.w d0,d7 ; form in low word: ??????????? hhhhh
-
- bsr.s fetch2 ; get minute, 0..59
- lsl.w #6,d7 ; form: ????? hhhhh 000000
- or.w d0,d7 ; add in the minutes
-
- bsr.s fetch2 ; get seconds, 0..59
- lsl.w #5,d7 ; form: hhhhh mmmmmm 00000
- lsr.w #1,d0 ; divide seconds by 2
- addx.w d0,d7 ; add in seconds (with rounding)
- *
- * --- set the TOS time [date : time ]
- *
- stdef: move.w d7,-(sp) ; pass the new time
- move.w #45,-(sp) ; pass function code = set time
- trap #1 ; call system
- addq.l #4,sp ; fix stack
- *
- * --- set the GEM date and time: [ date : time ]
- *
- move.l d7,-(sp) ; pass the date and time
- move.w #22,-(sp) ; pass function code = set date and time
- trap #14 ; call system
- addq.l #6,sp ; fix stack
- *
- * --- set the TOS date
- *
- swap d7 ; retrieve date to low word
- move.w d7,-(sp) ; pass the date
- move.w #43,-(sp) ; pass function code = set date
- trap #1 ; call system
- addq.l #4,sp ; fix stack
- rts
-
- * =====================================
- * ===== w_clock : write to clock =====
- * =====================================
- *
- * in: D0.B = data to be written
- * D1.W = register address x 2 to be written to
- *
- * out: A3.L = pointer to clock address latch
- * A4.L = pointer to clock chip select
- * D1.W = increased by 2
- * D0.W = data present prior to write
- * cc's : set by D0
- *
- * changed: A0,D2
- *
- * This subroutine is used to write data to the clock chip. The data
- * to be written is passed in the lower 4 bits of D0 and 2 times the
- * clock register to be accessed in passed in D1.
- *
- w_clock:
- lea ROM3,a3 ; LATCH address
- lea ROM4,a4 ; CS low strobe
- *
- * --- form the clock register address
- *
- wcep: lea 0(a3,d1.w),a0 ; form proper address
- *
- * --- mask off 4 bit data and align it into address bits 12..15
- *
- moveq #15,d2 ; load mask
- and.w d0,d2 ; mask of 4 bit data item
- ror.w #4,d2 ; rotate to upper bits
- *
- * --- latch address, data, and enable writes to the chip
- *
- move.b WRT(a0,d2.l),d0 ; read old data, latch new data
- *
- * --- turn chip select on to start the write operation
- *
- tst.w (a4) ; set chip select low
- addq.w #2,d1 ; update register address
- *
- * --- turn off write enable, turn off chip select, but hold data
- *
- tst.b READ(a0,d2.l) ; set chip select high
- andi.w #$000F,d0 ; mask off 4 bit data and set cond codes
- rts
-
- * =====================================
- * ===== r_clock : read from clock =====
- * =====================================
- *
- * in: A3.L = pointer to clock latch address
- * A4.L = pointer to chip select strobe address
- * A5.L = address of 16 byte buffer to be filled
- *
- * out: D0.L = 0 if all OK, else -1
- * cc's : set by D0
- * (A5) ---> [ flag bits ] leap count, AM/PM, 12/24 hour
- * +1 [ day of week ] 1=Sunday
- * +2 [ year x 10 ] 00 = 1980, 01 = 1981, etc.
- * +3 [ year x 1 ]
- * +4 [ month x 10 ]
- * +5 [ month x 1 ]
- * [ day x 10 ]
- * [ day x 1 ]
- * [ hour x 10 ]
- * [ hour x 1 ]
- * [ minute x 10 ]
- * [ minute x 1 ]
- * [ second x 10 ]
- * [ second x 1 ]
- * +14 [ .1 seconds ]
- * +15 [ junk byte ]
- *
- * changed: A0,D1,D2
- *
- * This subroutine reads all time and date registers from the clock chip
- * and fills a 16 byte buffer whose address was passed in A5. As the
- * information is read it is added up. Invalid sums typically indicate
- * a dead battery or a clock cartridge which is not present and are
- * indicated by returning a -1 in register D0 and the condition codes.
- * A data changed bit is check and if the time changed while the read
- * operation was in progress the operation is repeated.
- *
- r_clock:
- movea.l a3,a0 ; set pntr to register 0
- lea 16(a5),a5 ; point to end of buffer to fill
- moveq #0,d1 ; set accumulator to zero
- *
- * --- preload the register address in the latch
- *
- tst.w (a0)+ ; set register selection to 0
- *
- * --- loop and read clock registers 0..15
- *
- moveq #15,d2 ; loop count = 16
- fetch: tst.w (a4) ; set chip select on
- moveq #15,d0 ; load 4 bit data mask
- and.w (a0)+,d0 ; get data, set next addr, select off
- move.b d0,-(a5) ; store data in buffer
- add.w d0,d1 ; add up all data values
- dbf d2,fetch ; and repeat for 16 items
- *
- * --- retrieve data changed flag (zero indicates no change occurred)
- *
- tst.w (a4) ; set CS low with register select = 0
- moveq #8,d0 ; load mask
- and.w (a0),d0 ; get flag, nxt addr = 2, select = off
- *
- * --- if no clock present we generally accumulate 16x15 = 240
- *
- cmpi.w #125,d1 ; does accumulate indicate bad data?
- ble.s nwflg ; no, branch
- moveq #-1,d0 ; yes, set error flag
- *
- * --- test data changed flag and reread the time if necessary
- *
- nwflg: tst.w d0 ; was data changed (or an error)?
- bgt.s r_clock ; yes, then repeat the time reading
- rts ; no, exit with cond codes set
-
- * =========================================================
- * ===== xlate : Translate two bytes into ASCII digits =====
- * =========================================================
- *
- * in: A0.L = address of two bytes in the range 0..9
- * A1.L = destination address for ASCII digits
- * out: A0.L = incremented by 2
- * A1.L = incremented by 3
- * changed: none
- *
- * This subroutine converts two bytes addressed by A1 into ASCII digits
- * in the range '0..9' and increments the address pointer by 3.
- *
- xlate: bsr.s dt ; convert digit one
- bsr.s dt ; convert digit two
- addq.l #1,a1 ; skip ahead one place
- rts
-
- dt: move.b (a0)+,(a1) ; copy byte
- addi.b #$30,(a1)+ ; convert copied byte to ASCII
- rts
-
- * ===========================================
- * ===== B2D : Binary to Decimal String =====
- * ===========================================
- *
- * in: D0.W = value to convert, range = 0..99
- * A1.L = destination buffer
- * out: A1.L = incremented by 2
- * changed: D0
- *
- * This subroutine converts the value passed in D0.W which should be in
- * the range of 0..99 into a two digit ASCII string and stores these
- * digits at the address passed in A1.
- *
- b2d: ext.l d0 ; extend word into longword
- divu #10,d0 ; divide to separte ten's and one's
- addi.b #$30,d0 ; convert ten's digit to ASCII
- move.b d0,(a1)+ ; store ten's digit
- swap d0 ; swap remainder to low word
- addi.b #$30,d0 ; convert one's digit to ASCII
- move.b d0,(a1)+ ; store one's digit
- rts
-
- * ==================================================
- * ===== tod_fmt : format time of day and date =====
- * ==================================================
- *
- * in: A5.L = pointer to retrieved time buffer
- * out: none
- * changed: A0,A1,D0,D1,?
- *
- * This subroutine takes the data block returned by the subroutine
- * 'r_clock' and formats it into a string of the form:
- *
- * "WED 07-SEP-86 12:42 AM"
- *
- tod_fmt:
- lea time+3(pc),a1 ; address day of week field
- lea 1(a5),a0 ; pnt to day of week byte
-
- moveq #0,d0 ; ensure we start with zero
- move.b (a0)+,d0 ; get day of week, 1..7
- lsl.w #2,d0 ; form 4x which is byte offset
- move.l t_day-4(pc,d0.w),(a1)+ ; install string like "MON "
-
- addq.l #8,a1 ; address year field
- bsr fetch2 ; fetch the year, 0..99
- addi.w #80,d0 ; convert 0 into 80
- bsr.s b2d ; format as decimal string
-
- lea time+11(pc),a1 ; address month field
- bsr fetch2 ; fetch the month, 1..12
- lsl.w #2,d0 ; form 4x which is byte offset
- move.l month-4(pc,d0.w),(a1) ; install string like "JAN-"
-
- subq.l #3,a1 ; address day of month
- bsr.s xlate ; copy and translate day of the month
-
- addq.l #8,a1 ; address hours field
- bsr fetch2 ; fetch hours, 0..23
- moveq #$41,d2 ; preload "A" for AM
- tst.w d0 ; is time 00:xx ?
- bne.s ampm ; no, skip
- moveq #12,d0 ; yes, change 00:xx into 12:xx
- bra.s AM
-
- ampm: cmpi.w #12,d0 ; are we after noon?
- blt.s AM ; no, skip
- beq.s NOON ; if before 1:00pm just update character
- subi.w #12,d0 ; convert 13:00 into 1:00
- NOON: moveq #$50,d2 ; change character to "P"
-
- AM: bsr.s b2d ; format hours as decimal string
- addq.l #1,a1 ; advance over colon
- bsr.s xlate ; minutes
- bsr.s xlate ; seconds
-
- move.b d2,(a1) ; install AM or PM
- rts
- *
- * --- This is a table for converting 1..7 into a day of week string
- *
- t_day: dc.l 'Sun ','Mon ','Tue ','Wed '
- dc.l 'Thu ','Fri ','Sat '
- *
- * --- This is a table for converting 1..12 into a month string
- *
- month: dc.l 'Jan-','Feb-','Mar-','Apr-'
- dc.l 'May-','Jun-','Jul-','Aug-'
- dc.l 'Sep-','Oct-','Nov-','Dec-'
- *
- * --- the title and time and date display
- *
- title: dc.b CR,LF,LF
- dc.b '=TIMESET v1.0='
- time: dc.b CR,LF
- dc.b ' WED xx-xxx-xx xx:xx:xx xM'
- dc.b CR,LF,0
- *
- * --- error message
- *
- errmsg: dc.b CR,LF,BELL
- dc.b '=TIMESET='
- dc.b CR,LF
- dc.b ' * Check Clock Battery!'
- dc.b CR,LF,0
-
- end
-